package com.bix.util.blizfiles.dbc;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.bix.util.blizfiles.dbc.impl.CreatureDisplayInfo;
import com.bix.util.blizfiles.dbc.impl.CreatureDisplayInfoExtra;
import com.jme.util.resource.ResourceLocator;

/**
 * This is a factory class that is used to locate DBC files.
 * 
 * @author squid
 * 
 * @version 1.0.0
 */
public class DBCFileFactory implements ResourceLocator {
	private String parentDirectory;

	private Map<String, DBCFile<? extends DBCRecord>> dbcFiles = new HashMap<String, DBCFile<? extends DBCRecord>> ();

	/**
	 * Instantiate the file factory using the given parent directory of where to
	 * search for DBC files.
	 * 
	 * @param parentDirectory
	 *          The parent directory to search for DBC files.
	 * 
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	public DBCFileFactory(String parentDirectory) throws SecurityException, NoSuchMethodException {
		this.parentDirectory = parentDirectory;
		if (this.parentDirectory.endsWith ("\\") == false) {
			this.parentDirectory = this.parentDirectory + "\\";
		}

		//
		// Add the mappings to our factory.
		//
		dbcFiles.put ("CreatureDisplayInfo.dbc", new DBCFile<CreatureDisplayInfo> (CreatureDisplayInfo.class));
		dbcFiles.put ("CreatureDisplayInfoExtra.dbc",
				new DBCFile<CreatureDisplayInfoExtra> (CreatureDisplayInfoExtra.class));
	}

	/**
	 * Return a URL to a given resource.
	 * 
	 * @param resourceName
	 *          The name of the DBC file.
	 * 
	 * @return A URL to the given DBC file.
	 */
	public URL locateResource (String resourceName) {
		try {
			return new URL ("file:/" + this.parentDirectory + resourceName);
		} catch (MalformedURLException e) {
			e.printStackTrace ();
			return null;
		}
	}

	/**
	 * Returns the DBCFile implementation that was mapped to the given filename/
	 * resource name.
	 * 
	 * @param filename
	 *          The filename/resource.
	 * 
	 * @return The DBCFile mapped to the filename/resource.
	 * 
	 * @throws IOException
	 */
	public DBCFile<? extends DBCRecord> getDBCFile (String filename) throws IOException {
		if (filename.toLowerCase ().endsWith (".dbc") == false) {
			filename = filename + ".dbc";
		}
		return dbcFiles.get (filename).initialize (this.parentDirectory + filename);
	}

	/**
	 * So this is a stupid way to test something, but I'm too lazy atm to write
	 * junit test cases for this crap.
	 * 
	 * @param args
	 * @throws IOException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	public static void main (String args[]) throws IOException, SecurityException, NoSuchMethodException {
		//
		// Create a factory that points to the WoW DBC directory.
		//
		DBCFileFactory factory = new DBCFileFactory ("C:\\Program Files\\World of Warcraft\\dbc\\");

		//
		// Look up the creature info DBC file.
		//
		DBCFile<CreatureDisplayInfo> dbc = (DBCFile<CreatureDisplayInfo>) factory.getDBCFile ("CreatureDisplayInfo.dbc");
		for (int i = 0; i < dbc.getHeader ().getNumRecords (); i++) {
			CreatureDisplayInfo record = dbc.getRecord (i);
			System.out.println ("Record #" + i + ":" + record.toString ());
		}
	}
}
